package com.hospital.controller;

import com.google.gson.Gson;
import com.hospital.dao.WardStatusDao;
import com.hospital.dao.impl.WardStatusDaoImpl;
import com.hospital.dao.impl.WardBedPatientDao;
import com.hospital.dao.impl.PatientDao;
import com.hospital.model.DoctorView;
import com.hospital.model.WardStatusView;
import com.hospital.model.WardBedPatient;
import com.hospital.util.LoggerUtil;
import org.slf4j.Logger;
import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.http.HttpSession;

import java.io.IOException;
import java.sql.SQLException;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 病床转移处理Servlet
 * 处理患者换床请求
 */
@WebServlet("/bedTransfer/*")
public class BedTransferServlet extends HttpServlet {
    /** 日志记录器 */
    private static final Logger logger = LoggerUtil.getLogger();
    
    /** 病房状态数据访问对象，用于查询病房信息 */
    private WardStatusDao wardStatusDao = new WardStatusDaoImpl();
    
    /** 病房床位患者关联数据访问对象，用于管理床位信息 */
    private WardBedPatientDao wardBedPatientDao = new WardBedPatientDao();
    
    /** 患者数据访问对象，用于处理患者信息 */
    private PatientDao patientDao = new PatientDao();
    
    /** JSON转换工具对象，用于处理JSON数据的序列化和反序列化 */
    private Gson gson = new Gson();

    /**
     * 处理获取病床转移相关信息的GET请求
     * 支持以下路径：
     * /floors - 获取科室的楼层列表
     * /wards - 获取指定楼层的病房列表（仅返回有空床位的病房）
     * /beds - 获取指定病房的可用床位列表
     * 
     * @param req HTTP请求对象
     * @param resp HTTP响应对象
     * @throws ServletException Servlet异常
     * @throws IOException IO异常
     */
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) 
            throws ServletException, IOException {
        
        resp.setContentType("application/json;charset=UTF-8");
        String pathInfo = req.getPathInfo();
        
        // 获取当前登录的医生信息
        HttpSession session = req.getSession();
        DoctorView doctor = (DoctorView) session.getAttribute("doctor");
        
        if (doctor == null) {
            resp.setStatus(401);
            resp.getWriter().write("{\"error\": \"未登录\"}");
            return;
        }

        try {
            // 获取楼层列表
            if ("/floors".equals(pathInfo)) {
                List<Integer> floors = wardStatusDao.findFloorsByDeptId(doctor.getDeptId());
                resp.getWriter().write(gson.toJson(floors));
            }
            // 获取指定楼层的病房列表
            else if ("/wards".equals(pathInfo)) {
                int floorNum = Integer.parseInt(req.getParameter("floorNum"));
                List<WardStatusView> wards = wardStatusDao.findByDeptIdAndFloor(
                    doctor.getDeptId(), floorNum);
                // 只返回有空床位的病房
                wards = wards.stream()
                    .filter(ward -> ward.getAvailableBeds() > 0)
                    .collect(Collectors.toList());
                resp.getWriter().write(gson.toJson(wards));
            }
            // 获取指定病房的可用床位
            else if ("/beds".equals(pathInfo)) {
                int wardId = Integer.parseInt(req.getParameter("wardId"));
                List<WardBedPatient> beds = wardBedPatientDao.getWardBedsInfo(wardId);
                // 过滤出空闲的床位
                List<WardBedPatient> availableBeds = beds.stream()
                    .filter(bed -> bed.getBedStatus() == 2) // 2表示空闲
                    .collect(Collectors.toList());
                resp.getWriter().write(gson.toJson(availableBeds));
            }
            
        } catch (SQLException e) {
            e.printStackTrace();
            resp.setStatus(500);
            if (e.getMessage().contains("foreign key")) {
                resp.getWriter().write("{\"error\": \"数据库错误：床位不存在或已被占用\"}");
            } else {
                resp.getWriter().write("{\"error\": \"数据库错误：" + e.getMessage() + "\"}");
            }
        } catch (IllegalArgumentException e) {
            e.printStackTrace();
            resp.setStatus(400);
            resp.getWriter().write("{\"error\": \"参数错误：" + e.getMessage() + "\"}");
        } catch (SecurityException e) {
            e.printStackTrace();
            resp.setStatus(403);
            resp.getWriter().write("{\"error\": \"权限错误：" + e.getMessage() + "\"}");
        } catch (IOException e) {
            e.printStackTrace();
            resp.setStatus(500);
            resp.getWriter().write("{\"error\": \"IO错误：" + e.getMessage() + "\"}");
        }
    }

    /**
     * 处理病床转移的POST请求
     * @param req HTTP请求对象
     * @param resp HTTP响应对象
     * @throws ServletException Servlet异常
     * @throws IOException IO异常
     */
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) 
            throws ServletException, IOException {
        
        resp.setContentType("application/json;charset=UTF-8");
        req.setCharacterEncoding("UTF-8");
        
        // 获取当前登录的医生信息
        HttpSession session = req.getSession();
        DoctorView doctor = (DoctorView) session.getAttribute("doctor");
        
        if (doctor == null) {
            resp.setStatus(401);
            resp.getWriter().write("{\"error\": \"未登录\"}");
            return;
        }

        try {
            // 获取参数
            String patientIdStr = req.getParameter("patientId");
            String newBedIdStr = req.getParameter("newBedId");
            
            if (patientIdStr == null || newBedIdStr == null || 
                patientIdStr.trim().isEmpty() || newBedIdStr.trim().isEmpty()) {
                resp.setStatus(400);
                resp.getWriter().write("{\"error\": \"参数不完整\"}");
                return;
            }
            
            int patientId = Integer.parseInt(patientIdStr);
            int newBedId = Integer.parseInt(newBedIdStr);
            
            // 执行换床操作
            boolean success = patientDao.transferBed(patientId, newBedId);
            
            if (success) {
                resp.getWriter().write("{\"message\": \"换床成功\"}");
            } else {
                resp.setStatus(500);
                resp.getWriter().write("{\"error\": \"换床失败\"}");
            }
            
        } catch (NumberFormatException e) {
            resp.setStatus(400);
            resp.getWriter().write("{\"error\": \"无效的参数格式\"}");
        } catch (SQLException e) {
            e.printStackTrace();
            resp.setStatus(500);
            if (e.getMessage().contains("foreign key")) {
                resp.getWriter().write("{\"error\": \"数据库错误：床位不存在或已被占用\"}");
            } else {
                resp.getWriter().write("{\"error\": \"数据库错误：" + e.getMessage() + "\"}");
            }
        } catch (IllegalArgumentException e) {
            e.printStackTrace();
            resp.setStatus(400);
            resp.getWriter().write("{\"error\": \"参数错误：" + e.getMessage() + "\"}");
        } catch (SecurityException e) {
            e.printStackTrace();
            resp.setStatus(403);
            resp.getWriter().write("{\"error\": \"权限错误：" + e.getMessage() + "\"}");
        } catch (IOException e) {
            e.printStackTrace();
            resp.setStatus(500);
            resp.getWriter().write("{\"error\": \"IO错误：" + e.getMessage() + "\"}");
        }
    }
}